<template>
<div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片视图区域 -->
    <el-card>
      <!-- 添加角色按钮区域 -->
    <el-row>
      <el-col>
        <el-button type="primary" @click="addDialogVisible = true">添加角色</el-button>
      </el-col>
    </el-row>
    <!-- 角色列表区域 -->
    <el-table :data="roleslist" border stripe>
      <!-- 展开列 -->
    <el-table-column type="expand">
      <template v-slot="scope">
        <el-row :class="['bdbottom',i1 === 0 ? 'bdtop' : '','vcenter']" v-for="(item,i1) in scope.row.children" :key="item.id" class="bdbottom" >
          <!-- 渲染一级权限 -->
          <el-col :span="5">
            <el-tag>{{item.authName}}</el-tag>
            <i class="el-icon-caret-right"></i>
          </el-col>
          <!-- 渲染二级权限 -->
          <el-col :span="19">
            <!-- 通过for 循环 嵌套 渲染二级权限 -->
            <el-row :class="[i2 ===0 ? '' : 'bdtop','vcenter']" v-for="(item2,i2) in item.children" :key="item2">
              <el-col :span="9">
                <el-tag type="success">{{item2.authName}}</el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <el-col :span="10">
                <el-tag type="warning" 
                v-for="(item3) in item2.children" 
                :key="item3"   
                closable
                @close="removeRightById(scope.row,item3.id)">
                  {{item.authName}}
                </el-tag> 
              </el-col>
            </el-row>
          </el-col>
        </el-row>
      </template>
    </el-table-column>
      <!-- 索引列 -->
      <el-table-column type="index" label="#"></el-table-column>

      <!-- 字段名 -->
      <el-table-column label="角色名称" prop="roleName"></el-table-column>
      <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
      <el-table-column label="操作">
        <template v-slot="scope">
          <!-- 修改 -->
          <el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.id)">编辑</el-button>
          <!-- 删除 -->
          <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeUSerById(scope.row.id)">删除</el-button>
          <!-- 分配权限 -->
          <el-button type="warning" icon="el-icon-setting" size="mini" @click="showSetRightDialog(scope.row)">分配权限</el-button>
        </template>
      </el-table-column>
    </el-table>
    </el-card>

    <!-- 添加用户对话框 -->
  <el-dialog title="添加用户" :visible="addDialogVisible" width="50%" @close="addDialogClosed">
  <!-- 对话框 => 内容主体区 -->
  <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="80px">
  <el-form-item label="角色名称" prop="roleName">
    <el-input v-model="addForm.roleName"></el-input>
  </el-form-item>
    <el-form-item label="角色描述" prop="roleDesc">
    <el-input v-model="addForm.roleDesc"></el-input>
  </el-form-item>
  </el-form>
  <!-- 内容底部区域 -->
  <span slot="footer" class="dialog-footer">
    <el-button @click="addDialogVisible = false">取消</el-button>
    <el-button type="primary" @click="addroles">确定</el-button>
  </span>
</el-dialog>




<!-- 修改用户的对话框 -->
<el-dialog title="修改用户" :visible="editDialogVisible" width="50%" @close="editDialogClosed()">
<!-- 对话框中的表单 -->
<el-form :model="editForm" :rules="addFormRules" ref="editFormRef" label-width="70px">
  <el-form-item label="角色名称">
    <el-input v-model="editForm.roleName"></el-input>
  </el-form-item>
    <el-form-item label="角色描述" prop="roleDesc">
    <el-input  v-model="editForm.roleDesc"></el-input>
  </el-form-item>
</el-form>
 <!-- 修改对话框中的  取消 确定 按钮 -->
<span slot="footer" class="dialog-footer">
    <el-button @click="editDialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="editRolesInfo">确 定</el-button>
</span>
</el-dialog>


<!-- 分配权限对话框 -->
<el-dialog
  title="分配权限"
  :visible="SetRightDialogVisible"
  width="50%"
  @close="setRightsDialogClosed">
  <!-- 树形组件 -->
  <el-tree 
  :data="rightsList" 
  :props="treeProps" 
  show-checkbox
  node-key="id"
  default-expand-all="true"
  :default-checked-keys="defKeys"
  ref="treeRef">
  </el-tree>
  <span slot="footer" class="dialog-footer">
    <el-button @click="SetRightDialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="allotRights">确 定</el-button>
  </span>
</el-dialog>
</div>
</template>

<script>
export default {
  name:'Roles',
  data(){
    return {
      roleslist:[],
      // 控制 分配权限对话框 的显示与隐藏
      SetRightDialogVisible:false,
      // 所有权限数据
      rightsList:[],
      // 树形组件的属性绑定对象
      treeProps:{
        label:'authName',
        children:'children'
      },
      // 默认选中的节点id值
      defKeys:[],
      // 当前即将分配权限的角色id
      roleId:'',
  
     // 添加用户的表单数据
      addForm:{
        roleName:'',
        roleDesc:'',
      },
      // 查询到的用户信息对象
      editForm:{},
      // 添加用户对话框的显示和隐藏
      addDialogVisible : false,
      // 控制修改用户对话框的显示与隐藏
      editDialogVisible:false,
      // 添加表单的验证规则
      addFormRules:{
        roleName:[
        {
        required:true,
        message:'请输入用户名',
        trigger:'blur'
        },
        {
          min:3,
          max:10,
          message:'用户名长度为3-10之间',
          trigger:'blur'
        }
      ],
      roleDesc:[
        {
          message:'请输入对角色的描述',
          trigger:'blur'
        },
        {
          min:3,
          max:17,
          message:'描述限制在3-17之间',
          trigger:'blur'
        }
      ]
      },

    }
  },
  created(){
    this.getRolesList()
  },
  methods:{
    // 获取数据列表
    async getRolesList(){
     const {data:res} = await this.$http.get('roles')
     if(res.meta.status !== 200){
       return this.$message.error("获取用户信息失败")
     }
    //  console.log(this)
     this.roleslist = res.data
     console.log(this.roleslist)
    //  this.$message.success("获取角色列表成功")
    },
    // 监听添加用户对话框的关闭事件
    addDialogClosed(){
      this.$refs.addFormRef.resetFields()
    },
    // 添加用户
    addroles(){
      this.$refs.addFormRef.validate(async valid => {
        if(!valid) return
        // 可以发起添加用户的网络请求
         const {data:res} = await this.$http.post('roles',this.addForm)
         if(res.meta.status !== 201) return this.$message.error("添加用户失败") 
           this.$message.success("添加用户成功");
        //  添加用户成功之后隐藏用户的对话框
         this.addDialogVisible = false
        //  重新获取用户列表
         this.getRolesList()
        })
    },
        // 展示编辑用户的对话框
   async showEditDialog(id){
     console.log(id)
    const {data:res} = await this.$http.get('roles/' + id)
    if(res.meta.status !== 200){
      return this.$message.error("查询用户信息失败")
    }
    this.editForm = res.data
      this.editDialogVisible = true
    },
    // 修改用户信息并提交
    editRolesInfo(){
      this.$refs.editFormRef.validate(async valid => {
        if(!valid) return 
        // 通过了就发起修改用户信息的数据请求
        const {data:res} = await this.$http.put('roles/' + this.editForm.roleId,
        {
        roleName:this.editForm.roleName,
        roleDesc:this.editForm.roleDesc
        })
        if(res.meta.status !== 200){
          return this.$message.error("更新用户信息失败");
        }
        // 关闭对话框
        this.editDialogVisible = false
        // 刷新数据列表
        this.getRolesList()
        // 提示修改成功
        this.$message.success("更新用户信息成功");
      })
    },
        // 监听修改用户对话框的关闭事件
    editDialogClosed(){
      this.$refs.editFormRef.resetFields()
    },
    // 删除角色列表信息
    async removeUSerById(id){
    // 弹框 询问用户是否确认删除数据
    const confirmResult = await this.$confirm('此操作将永久删除该条数据,是否继续？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(err => err)
        // 如果用户确认删除  返回的是 字符串
        // 如果用户取消了删除 则返回的是 字符串 cancel
        // console.log(confirmResult)
        if(confirmResult !== 'confirm'){
          return this.$message.info('已取消删除操作');
        }
        // this.$message.success("删除成功")
        const {data:res} = await this.$http.delete('roles/' + id)
        if(res.meta.status !== 200){
          return this.$message.error("删除用户失败")
        }
        this.$message.success("删除用户成功");
        this.getRolesList()
    },
    async removeRightById(role,rightId){
      // 弹框提示用户是否删除
      const confirmResult = await this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(err => err)
        if(confirmResult !== 'confirm') {
          return this.$message.info('取消删除')
        }
        const {data:res}= await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
                  console.log(res)
        if(res.meta.status != 200) {
          return this.$message.error("删除权限失败")
        }
        this.$message.success("删除权限成功")
        // this.getRolesList()
        role.children = res.data
    },
    // 分配权限
    // 展示分配权限对话框
      async showSetRightDialog(role){
        this.roleId = role.id
        // 获取所有权限的数据
         const {data:res} = await this.$http.get('rights/tree')
         if(res.meta.status !== 200) {
           return this.$message.error("获取权限数据失败")
         }
        //  将获取到的权限数据保存到 data中的列表中
         this.rightsList = res.data
         console.log(this.rightsList)
        //  递归获取三级节点的id
        this.getLeafKeys(role,this.defKeys)
        this.SetRightDialogVisible = true
      },
      // 通过递归获取所有三级权限的id
      getLeafKeys(node,arr){
        if(!node.children) {
          // 如果当前id节点不包含 children 属性，那就是三级
          // 节点。  如果不是，就递归来 获取最终的三级节点
          return arr.push(node.id)
        }
        node.children.forEach(item => {
          this.getLeafKeys(item,arr)
        })
      },
      // 监听分配权限对话框的关闭事件
      setRightsDialogClosed(){
        this.defKeys = []
      },
      // 点击确定后 为角色分配权限
      async allotRights(){
        const keys=[
          ...this.$refs.treeRef.getCheckedKeys(),
          ...this.$refs.treeRef.getHalfCheckedKeys()
        ]
        // console.log(keys)
        const idStr = keys.join(',')
        const {data:res} = await this.$http.post(`roles/${this.roleId}/rights`,{ rids :  idStr})   
        if(res.meta.status !== 200){
          return this.$message.error("分配权限失败")
        } 
          this.$message.success("获取数据列表成功")
          this.getRolesList()
          this.SetRightDialogVisible = false      
      } 
  }

}
</script>

<style>
.el-tag {
  margin: 10px;
}
.bdtop{
  border-top: 1px solid #DEE1E6;
}
.bdbottom {
  border-bottom: 1px solid #DEE1E6;
}
.vcenter {
  display: flex;
  align-items: center;
}
</style>